using Abc.Core.Entities;

using Furion.DatabaseAccessor;
using Furion.DependencyInjection;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Tool;

namespace Abc.Core
{
    public class CacheService : ICacheService, ITransient
    {
        private readonly ILogger<CacheService> _logger;
        private readonly IRepository<Menu> _menuRepository;
        private readonly IRepository<DataConfig> _dataConfigRepository;
        private readonly IRepository<Permission> _permissionRepository;
        private readonly IRepository<Role> _roleRepository;
        private readonly IRepository<User> _userRepository;

        public CacheService(ILogger<CacheService> logger
     , IRepository<Menu> menuRepository
     , IRepository<DataConfig> dataConfigRepository
     , IRepository<Permission> permissionRepository
     , IRepository<Role> roleRepository
     , IRepository<User> userRepository)
        {
            _logger = logger;
            _menuRepository = menuRepository;
            _dataConfigRepository = dataConfigRepository;
            _permissionRepository = permissionRepository;
            _roleRepository = roleRepository;
            _userRepository = userRepository;
        }

        /// <summary>
        /// 刷新缓存
        /// </summary>
        /// <returns></returns>
        public async Task<ResultData<string>> RefreshCache()
        {
            await RefreshMenuMemberCache();
            await RefreshDataConfigMemberCache();
            await RefreshPermissionMemberCache();
            await RefreshRoleMemberCache();
            return new ResultData<string>() { Succeeded = true, Errors = "刷新成功" };
        }

        #region menu

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        public async Task<List<Menu>> GetMenuEntities()
        {
            var entities = await MemoryCacheExtension.GetMemoryCacheAsync<List<Menu>>(CacheConst.Menu);
            if (entities == null || entities.Count <= 0)
            {
                entities = await RefreshMenuMemberCache();
            }
            return entities;
        }

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        public async Task<List<Menu>> RefreshMenuMemberCache()
        {
            var entities = await _menuRepository.DetachedEntities.Include(o => o.Permissions).ToListAsync();
            entities.SetMemoryCache(CacheConst.Menu);
            return entities;
        }

        #endregion menu

        #region DataConfig

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        public async Task<List<DataConfig>> GetDataConfigEntities()
        {
            var entities = await MemoryCacheExtension.GetMemoryCacheAsync<List<DataConfig>>(CacheConst.DataConfig);
            if (entities == null || entities.Count <= 0)
            {
                entities = await RefreshDataConfigMemberCache();
            }
            return entities;
        }

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        public async Task<List<DataConfig>> RefreshDataConfigMemberCache()
        {
            var entities = await _dataConfigRepository.DetachedEntities.ToListAsync();
            entities.SetMemoryCache(CacheConst.DataConfig);
            return entities;
        }

        #endregion DataConfig

        #region Permission

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        public async Task<List<Permission>> GetPermissionEntities()
        {
            var entities = await MemoryCacheExtension.GetMemoryCacheAsync<List<Permission>>(CacheConst.Permission);
            if (entities == null || entities.Count <= 0)
            {
                entities = await RefreshPermissionMemberCache();
            }
            return entities;
        }

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        public async Task<List<Permission>> RefreshPermissionMemberCache()
        {
            var entities = await _permissionRepository.DetachedEntities.Include(o => o.Menus).ToListAsync();
            entities.SetMemoryCache(CacheConst.Permission);
            return entities;
        }

        #endregion Permission

        #region Role

        /// <summary>
        /// 查询所有角色
        /// </summary>
        /// <returns></returns>
        public async Task<List<Role>> GetRoleEntities()
        {
            var entities = await MemoryCacheExtension.GetMemoryCacheAsync<List<Role>>(CacheConst.Role);
            if (entities == null || entities.Count <= 0)
            {
                entities = await RefreshRoleMemberCache();
            }
            return entities;
        }

        /// <summary>
        /// 刷新角色内存缓存
        /// </summary>
        /// <returns></returns>
        public async Task<List<Role>> RefreshRoleMemberCache()
        {
            var entities = await _roleRepository.DetachedEntities.Include(o => o.Permissions).ToListAsync();
            entities.SetMemoryCache(CacheConst.Role);
            return entities;
        }

        #endregion Role

        #region 管理用户登陆

        /// <summary>
        /// 刷新登陆管理用户缓存
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public async Task RefreshLoginAdminUserCache(int userid)
        {
            var user = await MemoryCacheExtension.GetMemoryCacheAsync<User>($"Admin_{userid}");
            if (user != null)
            {
                var entity = await _userRepository.DetachedEntities.Include(o => o.Roles).ThenInclude(o => o.Permissions).FirstOrDefaultAsync(o => o.Id == userid);
                await SetLoginAdminUserCache(entity);
            }
        }

        /// <summary>
        /// 移除登陆管理用户缓存
        /// </summary>
        /// <param name="userids"></param>
        /// <returns></returns>
        public async Task RemoveLoginAdminUserCache(List<int> userids)
        {
            foreach (var userid in userids)
            {
                await MemoryCacheExtension.RemoveMemoryCacheAsync($"Admin_{userid}");
            }
        }

        /// <summary>
        /// 设置登陆管理用户缓存
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task SetLoginAdminUserCache(User user)
        {
            if (user == null) return;
            await user.SetMemoryCacheAsync($"Admin_{user.Id}", new Microsoft.Extensions.Caching.Memory.MemoryCacheEntryOptions()
            {
                SlidingExpiration = TimeSpan.FromMinutes(30),//滑动过期时间
            });
        }

        /// <summary>
        /// 验证权限
        /// </summary>
        ///  <param name="permissionType">权限类型</param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public async Task<bool> HasAuthorize(string permissionType, string controller, string action, int userid)
        {
            var user = await MemoryCacheExtension.GetMemoryCacheAsync<User>($"Admin_{userid}");
            if (user == null) return false;
            if (user.Account.ToLower().Trim() == "administrator".ToLower().Trim() || user.Account.ToLower().Trim() == "developer".ToLower().Trim())
            {
                return true;
            }

            foreach (var role in user.Roles)
            {
                var isHasAuthorize = role.Permissions.Any(o => o.Controller.ToLower().Trim() == controller.Trim().ToLower() && o.Actions.ToLower().Trim().Contains(action.ToLower().Trim()));
                if (isHasAuthorize) return true;
            }
            return false;
        }

        #endregion 管理用户登陆

        #region User  此处如果有大量用户，不适合，需要按需修改

        ///// <summary>
        ///// 查询所有角色
        ///// </summary>
        ///// <returns></returns>
        //public async Task<List<User>> GetUserEntities()
        //{
        //    var entities = await MemoryCacheExtension.GetMemoryCacheAsync<List<User>>(CacheConst.User);
        //    if (entities == null || entities.Count <= 0)
        //    {
        //        entities = await RefreshUserMemberCache();
        //    }
        //    return entities;
        //}

        ///// <summary>
        ///// 刷新角色内存缓存
        ///// </summary>
        ///// <returns></returns>
        //public async Task<List<User>> RefreshUserMemberCache()
        //{
        //    var entities = await _userRepository.DetachedEntities.Include(o => o.Roles).ThenInclude(o => o.Permissions).ToListAsync();
        //    entities.SetMemoryCache(CacheConst.User);
        //    return entities;
        //}

        #endregion User  此处如果有大量用户，不适合，需要按需修改
    }

    public interface ICacheService
    {
        /// <summary>
        /// 刷新缓存
        /// </summary>
        /// <returns></returns>
        Task<ResultData<string>> RefreshCache();

        #region menu

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        Task<List<Menu>> GetMenuEntities();

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        Task<List<Menu>> RefreshMenuMemberCache();

        #endregion menu

        #region DataConfig

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        Task<List<DataConfig>> GetDataConfigEntities();

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        Task<List<DataConfig>> RefreshDataConfigMemberCache();

        #endregion DataConfig

        #region Permission

        /// <summary>
        /// 查询所有菜单
        /// </summary>
        /// <returns></returns>
        Task<List<Permission>> GetPermissionEntities();

        /// <summary>
        /// 刷新菜单内存缓存
        /// </summary>
        /// <returns></returns>
        Task<List<Permission>> RefreshPermissionMemberCache();

        #endregion Permission

        #region Role

        /// <summary>
        /// 查询所有角色
        /// </summary>
        /// <returns></returns>
        Task<List<Role>> GetRoleEntities();

        /// <summary>
        /// 刷新角色内存缓存
        /// </summary>
        /// <returns></returns>
        Task<List<Role>> RefreshRoleMemberCache();

        #endregion Role

        #region 管理用户登陆

        /// <summary>
        /// 刷新登陆管理用户缓存
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        Task RefreshLoginAdminUserCache(int userid);

        /// <summary>
        /// 移除登陆管理用户缓存
        /// </summary>
        /// <param name="userids"></param>
        /// <returns></returns>
        Task RemoveLoginAdminUserCache(List<int> userids);

        /// <summary>
        /// 设置登陆管理用户缓存
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        Task SetLoginAdminUserCache(User user);

        /// <summary>
        /// 验证权限
        /// </summary>
        ///  <param name="permissionType">权限类型</param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        Task<bool> HasAuthorize(string permissionType, string controller, string action, int userid);

        #endregion 管理用户登陆
    }
}